﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Easyleave.Workflow;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using Easyleave.Logic.Domain;
using System.Workflow.Runtime.Tracking;
using System.Collections;

namespace Easyleave.Service
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class LeaveWorkflowService : ILeaveWorkflowService
    {
        private string SUCCSESS_MESSAGE = "Server operation succeeded!";
        private WorkflowRuntime workflowRuntime;
        private LocalDataExchangeService localService;

        public LeaveWorkflowService()
        {

        }

        private void SetUpWorkflowEnvironment()
        {
            if (localService == null)
            {
                WfWcfExtension extension =
                    OperationContext.Current.Host.Extensions.Find<WfWcfExtension>();
                workflowRuntime = extension.WorkflowRuntime;
                workflowRuntime.ServicesExceptionNotHandled += delegate(object sender, ServicesExceptionNotHandledEventArgs e)
                { bool workflowCompletedNormally = true; throw e.Exception; };
                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
                { bool workflowCompletedNormally = true; };
                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
                { bool workflowCompletedNormally = true; };
                workflowRuntime.WorkflowAborted += delegate(object sender, WorkflowEventArgs e)
                { bool workflowCompletedNormally = true; };
                workflowRuntime.WorkflowSuspended += delegate(object sender, WorkflowSuspendedEventArgs e)
                { bool workflowCompletedNormally = true; };  
                ExternalDataExchangeService dataExchangeService = workflowRuntime.GetService<ExternalDataExchangeService>();
                localService = (LocalDataExchangeService)dataExchangeService.GetService(typeof(LocalDataExchangeService));

                if (localService == null)
                {
                    localService = new LocalDataExchangeService();
                    dataExchangeService.AddService(localService);
                }
            }
 
        }

        #region ILeaveService Members

        public Guid SubmitNewLeaveRequest(Guid? authorId, LeaveDto leave)
        {
            SetUpWorkflowEnvironment();
            Type workflowType = typeof(LeaveWorkflow);
            WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow(workflowType);
            workflowInstance.Start();
            localService.SubmitLeave(workflowInstance.InstanceId, authorId, leave);
            return workflowInstance.InstanceId;
        }

        public string RecommendLeaveRequest(Guid leaveId, Guid? authorId, string message)
        {
            SetUpWorkflowEnvironment();
            localService.RecommendLeave(leaveId, authorId, message);
            return SUCCSESS_MESSAGE;
        }


        public string ApproveLeaveRequest(Guid leaveId, Guid? authorId, string message)
        {
            SetUpWorkflowEnvironment();
            localService.ApproveLeave(leaveId, authorId, message);
            return SUCCSESS_MESSAGE;
        }

        public string RejectLeaveRequest(Guid leaveId, Guid? authorId, string message)
        {
            SetUpWorkflowEnvironment();
            localService.RejectLeave(leaveId, authorId, message);
            return SUCCSESS_MESSAGE;
        }

        /// <summary>
        /// Get the leave objects reported by the given user
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IList<LeaveDto> GetLeavesSubmittedByMe(Guid? userId)
        {
            LeaveDataManager dataMgr = new LeaveDataManager();
            return dataMgr.GetRecordsByOwner(userId);
        }

        public IList<LeaveDto> GetLeavesToBeRecommendedByMe(Guid? userId)
        {
            LeaveDataManager dataMgr = new LeaveDataManager();
            return dataMgr.GetRecordsByRecommender(userId);
        }

        public IList<LeaveDto> GetLeavesToBeApprovedByMe(Guid? userId)
        {
            LeaveDataManager dataMgr = new LeaveDataManager();
            return dataMgr.GetRecordsByApprover(userId);
        }

        #endregion
    }
}
